package com.fwtai.service.web;

import com.alibaba.fastjson2.JSONObject;
import com.fwtai.bean.PageFormData;
import com.fwtai.bean.UploadFile;
import com.fwtai.bean.UploadObject;
import com.fwtai.config.ConfigFile;
import com.fwtai.tool.ToolClient;
import com.fwtai.tool.ToolString;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.List;

/**
 * KindEditor富文本编辑器图片上传处理
 * @作者 田应平
 * @版本 v1.0
 * @QQ号码 444141300
 * @创建日期 2021-07-23 11:23:29
 * @官网 <url>http://www.fwtai.com</url>
*/
@Service
public class EditorService{

  @Value("${upload_dir_window}")
  private String dir_window;

  @Value("${upload_dir_linux}")
  private String dir_linux;

  private String imageUrl = "https://file.jiangzhonggujiu.com";//需要在nginx配置路径

  private String prefixType = "/editor/";// 访问路径示例:http://192.168.1.121:1011/editor/image/20220801/fffffffff34bbace0000000071cf3a93.png

  public String upload(final HttpServletRequest request){
    final PageFormData formData = new PageFormData(request);
    final String dir = formData.getString("dir");//dir->image|media
    final String baseDir = ToolString.isLinuxOS() ? dir_linux : dir_window;
    final UploadObject uploadObject = ToolClient.uploadFile(request,baseDir,prefixType+dir,false,1,4,true);
    final String errorMsg = uploadObject.getErrorMsg();
    if(errorMsg != null) return ToolClient.createJsonFail(errorMsg);
    final ArrayList<UploadFile> listFiles = uploadObject.getListFiles();
    if(listFiles == null || listFiles.size() <= 0) return ToolClient.createJsonFail("请选择上传文件");
    final UploadFile uploadFile = listFiles.get(0);
    formData.put("url",imageUrl+uploadFile.getUrlFile());
    return ToolClient.queryJson(formData);
  }

  /*
  nginx配置
  server {
    listen 8103;
    charset utf-8;
    default_type  "text/html;charset=utf-8";
    server_name localhost;
    #服务端本地路径:/home/data/hospital/files/editor/image/20220801/fffffffff34bbace0000000071cf3a93.png,其中/home/data/hospital/files/是文件所在的根目录;
    #访问路径:http://192.168.1.121:1011/editor/image/20220801/fffffffff34bbace0000000071cf3a93.png
    location ~* ^/editor/(.*\.(png|jpg|gif|jpeg|svg|mp4|avi))$ {
      expires 24h;
      root root /home/data/hospital/files/;#文件根目录
      proxy_store on;
      proxy_store_access user:rw group:rw all:rw;
      proxy_redirect     off;
      client_max_body_size  10m;
      client_body_buffer_size 1280k;
      proxy_connect_timeout  900;
      proxy_send_timeout   900;
      proxy_read_timeout   900;
      proxy_buffer_size    40k;
      proxy_buffers      40 320k;
      proxy_busy_buffers_size 640k;
      proxy_temp_file_write_size 640k;
    }
    error_page   500 503 504  /50x.html;
    location = /50x.html {
       root   html;
    }
    error_page  502         =200 /cdcweb502;
    location =/cdcweb502 {
      set $ret_body '{"code": 502,"msg": "系统升级,稍候重试"}';
      return 200 $ret_body;
    }
  }

  */
  public String getFiles(final HttpServletRequest request){
    final String dir = request.getParameter("dir");//dir->image|media
    final String rootPath = (ToolString.isLinuxOS() ? dir_linux : dir_window) + prefixType+dir+"/";
    final String rootUrl = imageUrl+prefixType+dir+"/";
    //图片扩展名
    final String[] fileTypes = new String[]{"gif","jpg","jpeg","png","bmp","svg","webp"};
    //根据path参数，设置各路径和URL
    final String path = request.getParameter("path") != null ? request.getParameter("path") : "/";
    final String currentPath = rootPath + path;
    final String currentUrl = rootUrl + path;
    final String moveupDirPath = "";
    //排序形式，name or size or type
    final String order = request.getParameter("order") != null ? request.getParameter("order").toLowerCase() : "name";
    final JSONObject result = new JSONObject();
    //不允许使用..移动到上一级目录
    if (path.indexOf("..") >= 0) {
      result.put(ConfigFile.code,ConfigFile.code199);
      result.put(ConfigFile.msg,"无权限访问");
      return result.toJSONString();
    }
    //最后一个字符不是/
    if (!"".equals(path) && !path.endsWith("/")) {
      result.put(ConfigFile.code,ConfigFile.code199);
      result.put(ConfigFile.msg,"无效的参数");
      return result.toJSONString();
    }
    //目录不存在或不是目录
    final File currentPathFile = new File(currentPath);
    if(!currentPathFile.isDirectory()){
      result.put(ConfigFile.code,ConfigFile.code201);
      result.put(ConfigFile.msg,"暂无数据或无效的目录");
      return result.toJSONString();
    }
    //遍历目录取的文件信息
    final List<Hashtable<String,Object>> fileList = new ArrayList<>();
    if(currentPathFile.listFiles() != null) {
      for (File file : currentPathFile.listFiles()) {
        final Hashtable<String,Object> hash = new Hashtable<String,Object>();
        final String fileName = file.getName();
        if(file.isDirectory()) {
          hash.put("is_dir", true);
          hash.put("has_file", (file.listFiles() != null));
          hash.put("filesize", 0L);
          hash.put("is_photo", false);
          hash.put("filetype", "");
        } else if(file.isFile()){
          String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
          hash.put("is_dir", false);
          hash.put("has_file", false);
          hash.put("filesize", file.length());
          hash.put("is_photo", Arrays.<String>asList(fileTypes).contains(fileExt));
          hash.put("filetype", fileExt);
        }
        hash.put("filename", fileName);
        hash.put("datetime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.lastModified()));
        fileList.add(hash);
      }
    }
    if ("size".equals(order)) {
      Collections.sort(fileList, new SizeComparator());
    } else if ("type".equals(order)) {
      Collections.sort(fileList, new TypeComparator());
    } else {
      Collections.sort(fileList, new NameComparator());
    }
    result.put("moveup_dir_path",moveupDirPath);
    result.put("current_dir_path",path);
    result.put("current_url",currentUrl);
    result.put("total_count",fileList.size());
    if(fileList.size() > 0){
      result.put("file_list", fileList);
      result.put(ConfigFile.code,ConfigFile.code200);
      result.put(ConfigFile.msg,ConfigFile.msg200);
      return result.toJSONString();
    }else{
      return ToolClient.queryEmpty("无效的目录或暂无文件");
    }
  }

  static class NameComparator<Integer> implements Comparator<Integer>{
    public int compare(Object a, Object b) {
      final Hashtable hashA = (Hashtable)a;
      final Hashtable hashB = (Hashtable)b;
      if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) {
        return -1;
      } else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) {
        return 1;
      } else {
        return ((String)hashA.get("filename")).compareTo((String)hashB.get("filename"));
      }
    }
  }
  static class SizeComparator<Integer> implements Comparator<Integer> {
    public int compare(Object a, Object b) {
      final Hashtable hashA = (Hashtable)a;
      final Hashtable hashB = (Hashtable)b;
      if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) {
        return -1;
      } else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) {
        return 1;
      } else {
        if (((Long)hashA.get("filesize")) > ((Long)hashB.get("filesize"))) {
          return 1;
        } else if (((Long)hashA.get("filesize")) < ((Long)hashB.get("filesize"))) {
          return -1;
        } else {
          return 0;
        }
      }
    }
  }
  static class TypeComparator<Integer> implements Comparator<Integer> {
    public int compare(Object a, Object b) {
      final Hashtable hashA = (Hashtable)a;
      final Hashtable hashB = (Hashtable)b;
      if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) {
        return -1;
      } else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) {
        return 1;
      } else {
        return ((String)hashA.get("filetype")).compareTo((String)hashB.get("filetype"));
      }
    }
  }
}